#include "Help.h"
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "BinaryToBase64.h"
#include "Base64ToBinary.h"
#include "Validation.h"
#include "Constants.h"
#include "Errors.h"

int main(int argc, char** argv) {

	int next_option;
	int encoderMode = 0; /* 1 si esta activo */
	int decoderMode = 0; /* 1 si esta activo */
	int state = 0;
	char* inputFilename = NULL;
	char* outputFilename = NULL;
	int paramCounter = 1; /* Puntero de argumentos que recibe el programa */
	FILE *input = NULL, *output = NULL;
	int cierreDeArchivo = 0;

	const char* const short_options = "hediov";
	const struct option long_options[] = { { "help", 0, NULL, 'h' }, { "encode",
			0, NULL, 'e' }, { "decode", 0, NULL, 'd' },
			{ "input", 0, NULL, 'i' }, { "output", 0, NULL, 'o' }, { "version",
					0, NULL, 'v' }, { NULL, 0, NULL, 0 } };
	do {
		next_option = getopt_long(argc, argv, short_options, long_options,
				NULL);
		switch (next_option) {
		case 'h':
			printHelp(argv[0]);
			exit(0);

		case 'e':
			encoderMode = 1;
			paramCounter++;
			break;

		case 'd':
			decoderMode = 1;
			paramCounter++;
			break;

		case 'i':
			inputFilename = argv[paramCounter + 1];
			paramCounter += 2;
			break;

		case 'o':
			outputFilename = argv[paramCounter + 1];
			paramCounter += 2;
			break;

		case 'v':
			printVersion();
			exit(0);

		case '?':
			exit(1);

		default:
			break;
		}

	} while (next_option != -1);

	if (encoderMode == 1 && decoderMode == 1) {
		printOnlyOneMode();
	}

	if (encoderMode == 0 && decoderMode == 0) {
		printOneModeIsNeeded();
	}

	if (inputFilename == NULL || *inputFilename == '-') {
		input = stdin;
	} else {
		input = fopen(inputFilename, "rb");
		if (input == NULL)
			file_error("Error al intentar abrir el archivo de entrada.\n");
	}
	if (outputFilename == NULL || *outputFilename == '-') {
		output = stdout;
	} else {
		output = fopen(outputFilename, "wb");
		if (output == NULL)
			file_error("Error al intentar abrir el archivo de salida.\n");
	}

	if (encoderMode == 1) {
		binaryToBase64(input, output);
	} else if (decoderMode == 1) {
		base64ToBinary(input, output);

	}

	if (inputFilename != NULL)
		cierreDeArchivo = fclose(input);
	if (cierreDeArchivo != 0)
		file_error("Error al cerrar el archivo de entrada.\n");

	if (outputFilename != NULL)
		cierreDeArchivo = fclose(output);
	if (cierreDeArchivo != 0)
		file_error("Error al cerrar el archivo de salida.\n");

	return state;
}
